From 590d9c58a14eb1844b49f91498cbe4cfac43cbb6 Mon Sep 17 00:00:00 2001 From: "shand@ubuntu.eng.hq.xensource.com" Date: Wed, 14 Sep 2005 17:45:51 -0800 Subject: [PATCH] Make sure xend start doesn't return until xend is ready to accept connections. This means xend start && xm list actually works now (instead of throwing an exception). Signed-off-by: Anthony Liguori --- tools/misc/xend | 3 -- tools/python/xen/web/httpserver.py | 4 +++ tools/python/xen/xend/server/SrvDaemon.py | 37 ++++++++++++++--------- tools/python/xen/xend/server/SrvServer.py | 22 +++++++++++++- 4 files changed, 48 insertions(+), 18 deletions(-) diff --git a/tools/misc/xend b/tools/misc/xend index 1777c6488f..e1a6b4f437 100644 --- a/tools/misc/xend +++ b/tools/misc/xend @@ -86,9 +86,6 @@ def main(): daemon = SrvDaemon.instance() if not sys.argv[1:]: print 'usage: %s {start|stop|restart}' % sys.argv[0] - elif os.fork(): - pid, status = os.wait() - return status >> 8 elif sys.argv[1] == 'start': start_xenstored() start_consoled() diff --git a/tools/python/xen/web/httpserver.py b/tools/python/xen/web/httpserver.py index 6c06e44764..394dba2759 100644 --- a/tools/python/xen/web/httpserver.py +++ b/tools/python/xen/web/httpserver.py @@ -273,6 +273,9 @@ class HttpServer: self.interface = interface self.port = port self.root = root + # ready indicates when we are ready to begin accept connections + # it should be set after a successful bind + self.ready = False def getRoot(self): return self.root @@ -283,6 +286,7 @@ class HttpServer: def run(self): self.bind() self.listen() + self.ready = True self.requestLoop() def stop(self): diff --git a/tools/python/xen/xend/server/SrvDaemon.py b/tools/python/xen/xend/server/SrvDaemon.py index c8fc1ff384..378497e557 100644 --- a/tools/python/xen/xend/server/SrvDaemon.py +++ b/tools/python/xen/xend/server/SrvDaemon.py @@ -137,13 +137,6 @@ class Daemon: else: return 0 - def onSIGCHLD(self, signum, frame): - if self.child > 0: - try: - pid, sts = os.waitpid(self.child, os.WNOHANG) - except os.error, ex: - pass - def fork_pid(self, pidfile): """Fork and write the pid of the child to 'pidfile'. @@ -200,15 +193,29 @@ class Daemon: # Trying to run an already-running service is a success. return 0 - signal.signal(signal.SIGCHLD, self.onSIGCHLD) + ret = 0 + + # we use a pipe to communicate between the parent and the child process + # this way we know when the child has actually initialized itself so + # we can avoid a race condition during startup + + r,w = os.pipe() if self.fork_pid(XEND_PID_FILE): - #Parent. Sleep to give child time to start. - time.sleep(1) + os.close(w) + r = os.fdopen(r, 'r') + s = r.read() + r.close() + if not len(s): + ret = 1 + else: + ret = int(s) else: + os.close(r) # Child self.tracing(trace) - self.run() - return 0 + self.run(os.fdopen(w, 'w')) + + return ret def tracing(self, traceon): """Turn tracing on or off. @@ -290,7 +297,7 @@ class Daemon: def stop(self): return self.cleanup(kill=True) - def run(self): + def run(self, status): _enforce_dom0_cpus() try: log.info("Xend Daemon started") @@ -298,12 +305,14 @@ class Daemon: relocate.listenRelocation() servers = SrvServer.create() self.daemonize() - servers.start() + servers.start(status) except Exception, ex: print >>sys.stderr, 'Exception starting xend:', ex if XEND_DEBUG: traceback.print_exc() log.exception("Exception starting xend (%s)" % ex) + status.write('1') + status.close() self.exit(1) def exit(self, rc=0): diff --git a/tools/python/xen/xend/server/SrvServer.py b/tools/python/xen/xend/server/SrvServer.py index 12a2f5ff5c..ecd4975728 100644 --- a/tools/python/xen/xend/server/SrvServer.py +++ b/tools/python/xen/xend/server/SrvServer.py @@ -48,6 +48,7 @@ from xen.xend import XendRoot; xroot = XendRoot.instance() from xen.xend import Vifctl from xen.xend.XendLogging import log from xen.web.SrvDir import SrvDir +import time from SrvRoot import SrvRoot @@ -59,7 +60,7 @@ class XendServers: def add(self, server): self.servers.append(server) - def start(self): + def start(self, status): Vifctl.network('start') threads = [] for server in self.servers: @@ -67,6 +68,25 @@ class XendServers: thread.start() threads.append(thread) + + # check for when all threads have initialized themselves and then + # close the status pipe + + threads_left = True + while threads_left: + threads_left = False + + for server in self.servers: + if not server.ready: + threads_left = True + break + + if threads_left: + time.sleep(.5) + + status.write('0') + status.close() + for t in threads: t.join() -- 2.30.2